﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CueMounter.DokanStructure.RamDisk {
	public class DokanRamDiskDirectory : DokanDirectory {
		private List<DokanRamDiskDirectory> directories = new List<DokanRamDiskDirectory>();
		private List<DokanRamDiskFile> files = new List<DokanRamDiskFile>();

		public DokanRamDiskDirectory(string name) {
			Name = name;
		}

		public override DokanDirectory[] Directories {
			get {
				return directories.ToArray();
			}
		}

		public override DokanFile[] Files {
			get {
				return files.ToArray();
			}
		}

		public void CreateDirectory(DokanRamDiskDirectory directory) {
			if(GetDirectory(directory.Name) == null) {
				directories.Add(directory);
			}
		}

		public override void CreateDirectory(string name) {
			if(GetDirectory(name) == null) {
				directories.Add(new DokanRamDiskDirectory(name));
			}
		}

		public void DeleteDirectory(DokanRamDiskDirectory directory) {
			if(!directories.Remove(directory)) {
				throw new DirectoryNotFoundException();
			}
		}

		public override void DeleteDirectory(string name) {
			if(!directories.Remove((DokanRamDiskDirectory)GetDirectory(name))) {
				throw new DirectoryNotFoundException();
			}
		}

		public void CreateFile(DokanRamDiskFile file) {
			if(GetFile(file.Name) == null) {
				files.Add(file);
			} else {
				throw new IOException();
			}
		}

		public override void CreateFile(string name) {
			if(GetFile(name) == null) {
				files.Add(new DokanRamDiskFile(name));
			} else {
				throw new IOException();
			}
		}

		public void DeleteFile(DokanRamDiskFile file) {
			if(!files.Remove(file)) {
				throw new FileNotFoundException();
			}
		}

		public override void DeleteFile(string name) {
			if(!files.Remove((DokanRamDiskFile)GetFile(name))) {
				throw new FileNotFoundException();
			}
		}

		public override void MoveDirectory(string[] oldPath, string[] newPath, bool replace) {
			string[] oldContainerPath = oldPath.Take(oldPath.Length - 1).ToArray();
			string[] newContainerPath = newPath.Take(newPath.Length - 1).ToArray();

			DokanRamDiskDirectory directory = (DokanRamDiskDirectory)GetDirectory(oldPath);
			DokanRamDiskDirectory oldContainer = (DokanRamDiskDirectory)GetDirectory(oldContainerPath);
			DokanRamDiskDirectory newContainer = (DokanRamDiskDirectory)GetDirectory(newContainerPath);

			if(directory == null || oldContainer == null || newContainer == null) {
				throw new IOException();
			}

			oldContainer.DeleteDirectory(directory);
			directory.Name = newPath[newPath.Length - 1];
			newContainer.CreateDirectory(directory);
		}

		public override void MoveFile(string[] oldPath, string[] newPath, bool replace) {
			string[] oldContainerPath = oldPath.Take(oldPath.Length - 1).ToArray();
			string[] newContainerPath = newPath.Take(newPath.Length - 1).ToArray();

			DokanRamDiskFile file = (DokanRamDiskFile)GetFile(oldPath);
			DokanRamDiskDirectory oldContainer = (DokanRamDiskDirectory)GetDirectory(oldContainerPath);
			DokanRamDiskDirectory newContainer = (DokanRamDiskDirectory)GetDirectory(newContainerPath);

			if(file == null || oldContainer == null || newContainer == null) {
				throw new IOException();
			}

			oldContainer.DeleteFile(file);
			file.Name = newPath[newPath.Length - 1];
			newContainer.CreateFile(file);
		}
	}
}
